from flask import g, render_template, abort, request, jsonify, current_app

from info import db
from info.constants import USER_COLLECTION_MAX_NEWS, QINIU_DOMIN_PREFIX, HOME_PAGE_MAX_NEWS
from info.models import UserCollection, Category, News

from info.modules.user import user_blu
from info.utils.commont_filter import user_login_data, file_upload

from info.utils.response_code import error_map, RET


# 个人中心展示
@user_blu.route('/user_info')
@user_login_data
def user_info():
    user = g.user
    if not user:
        return abort(403)

    return render_template("user.html", user=user.to_dict())


# 基本资料
@user_blu.route('/base_info', methods=["GET", "POST"])
@user_login_data
def base_info():
    user = g.user
    if not user:
        return abort(403)

    # 如果是get请求
    if request.method == "GET":
        return render_template("user_base_info.html", user=user.to_dict())

    # 如果是post请求
    # 个性签名
    signature = request.json.get("signature")
    # 昵称
    nick_name = request.json.get("nick_name")
    # 性别
    gender = request.json.get("gender")

    # 校验参数
    if not all([signature, nick_name, gender]):
        return jsonify(errmsg=error_map[RET.PARAMERR], errno=RET.PARAMERR)

    if gender not in ["MAN", "WOMAN"]:
        return jsonify(errmsg=error_map[RET.PARAMERR], errno=RET.PARAMERR)

    # 修改用户对象
    try:
        user.gender = gender
        user.signature = signature
        user.nick_name = nick_name
        # 提交到会话中
        db.session.add(user)
    except BaseException as e:
        current_app.logger.error(e)
        db.session.rollback()
        return abort(500)

    # 返回json
    return jsonify(errmsg=error_map[RET.OK], errno=RET.OK)


# 头像的设置
@user_blu.route('/pic_info', methods=["GET", "POST"])
@user_login_data
def pic_info():
    # 判断用户是否登陆
    user = g.user

    if not user:
        return abort(403)

    # 判断如果是get请求
    if request.method == "GET":
        return render_template("user_pic_info.html", user=user.to_dict())

    # 如果是post
    avatar_file = request.files.get("avatar")

    # 读取文件 生成二进制数据
    avatar_bytes = avatar_file.read()
    # 上传图片
    file_name = file_upload(avatar_bytes)
    try:
        user.avatar_url = file_name
    except BaseException as e:
        current_app.logger.error(e)
        return jsonify(errmsg=error_map[RET.THIRDERR], errno=RET.THIRDERR)
    # 返回json
    return jsonify(errmsg=error_map[RET.OK], errno=RET.OK, data=user.to_dict())


@user_blu.route('/pass_info', methods=["GET", "POST"])
@user_login_data
def pass_info():
    user = g.user
    if not user:
        return abort(403)  # 如果查不到用户拒绝访问

    # 如果是get请求  # current_app.send_static_file直接返回静态页面
    if request.method == "GET":
        return current_app.send_static_file("/news/html/user_pass_info.html")

    # 如果是post请求
    # 获取参数
    old_password = request.json.get('old_password')
    new_password = request.json.get('new_password')

    # 校验参数
    if not all([old_password, new_password]):
        return jsonify(errmsg=error_map[RET.PARAMERR], errno=RET.PARAMERR)

    # 校验旧密码
    if not user.check_password_hash(old_password):
        return jsonify(errmsg=error_map[RET.PWDERR], errno=RET.PWDERR)

    # 数据库中修改数据
    try:
        user.password = new_password
    except BaseException as e:
        current_app.logger.error(e)
        return jsonify(errmsg=error_map[RET.DBERR], errno=RET.DBERR)

    # 返回json
    return jsonify(errmsg=error_map[RET.OK], errno=RET.OK)


# 我的收藏
@user_blu.route('collection')
@user_login_data
def collection():
    user = g.user
    if not user:
        return abort(403)

    # 获取参数
    # 获取当前页码,如果不设置默认为1
    p = request.args.get('p', 1)

    # 校验参数
    try:
        p = int(p)
    except BaseException as e:
        current_app.logger.error(e)
        return jsonify(errmsg=error_map[RET.PARAMERR], errno=RET.PARAMERR)

    # 查询该用户收藏的所有新闻,按照收藏时间进行排序,分页展示
    try:
        pn = user.collection_news.order_by(UserCollection.create_time.desc()).paginate(p, USER_COLLECTION_MAX_NEWS)
    except BaseException as e:
        current_app.logger.error(e)
        return abort(500)

    news_list = []
    for news in pn.items:
        # 查询新闻收藏关系表的一个对象
        try:
            collect_time = UserCollection.query.filter_by(news_id=news.id).first()
        except BaseException as e:
            current_app.logger.error(e)
            return jsonify(errmsg=error_map[RET.DBERR], errno=RET.DBERR)
        news_dict = news.to_dict()
        news_dict["collect_create_time"] = collect_time.create_time
        news_list.append(news_dict)

    # 将新闻列表,总页数和当前页数进行返回
    data = {
        "news_list": news_list,
        "total_page": pn.pages,
        "cur_page": pn.page
    }

    return render_template("user_collection.html", user=user.to_dict(), data=data)


# 新闻发布
@user_blu.route('/news_release', methods=['GET', 'POST'])
@user_login_data
def news_release():
    user = g.user
    if not user:
        return abort(403)
    # 如果是get请求
    if request.method == 'GET':
        # 查询所有的分类
        try:
            categories = Category.query.filter(Category.id != 1).all()
        except BaseException as e:
            current_app.logger.error(e)
            return abort(500)

        # 返回页面
        return render_template('user_news_release.html', user=user.to_dict(), categories=categories)

    # 如果是post请求
    # 获取参数
    # 新闻标题
    title = request.form.get('title')
    # 新闻分类
    category_id = request.form.get('category_id')
    # 摘要
    digest = request.form.get('digest')
    # 内容
    content = request.form.get('content')
    # 图片
    index_image = request.files.get('index_image')

    # 校验参数
    if not all([title, category_id, digest, content, index_image]):
        return jsonify(errmsg=error_map[RET.PARAMERR], errno=RET.PARAMERR)

    # 生成一条新闻
    news = News()
    news.title = title
    news.digest = digest
    news.source = user.nick_name
    news.content = content
    news.category_id = category_id
    news.user_id = user.id
    news.status = 1
    # 获取图片路径
    try:
        image_bytes = index_image.read()
        file_name = file_upload(image_bytes)
        news.index_image_url = QINIU_DOMIN_PREFIX + file_name

    except BaseException as e:
        current_app.logger.error(e)
        return jsonify(errmsg=error_map[RET.THIRDERR], errno=RET.THIRDERR)

    # 添加到会话中
    try:
        db.session.add(news)
    except BaseException as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errmsg=error_map[RET.DBERR], errno=RET.DBERR)

    return jsonify(errmsg=error_map[RET.OK], errno=RET.OK)


# 新闻列表
@user_blu.route('/news_list')
@user_login_data
def news_list():
    user = g.user
    if not user:
        return abort(403)

    # 获取参数 设置默认值为1
    p = request.args.get('p', 1)

    # 校验参数
    try:
        p = int(p)
    except BaseException as e:
        current_app.logger.error(e)
        return jsonify(errmsg=error_map[RET.PARAMERR], errno=RET.PARAMERR)

    # 查询用户发布的所有新闻,按照发布时间进行降序
    try:
        pn = user.news_list.order_by(News.create_time.desc()).paginate(p, HOME_PAGE_MAX_NEWS)
    except BaseException as e:
        current_app.logger.error(e)
        return abort(500)

    data = {
        "news_list": [news.to_review_dict() for news in pn.items],
        "total_page": pn.pages,
        "cur_page": pn.page
    }

    return render_template('user_news_list.html', data=data)
